package com.cskaoyan.javase.object._3equals;


/**
 * 细节一:
 * 在重写equals方法的时候,需要对传入的对象做排它性校验
 * 实现排它性有以下两种方式:
 *      1.用getClass方法来校验排它性是非常严格的
 *          只要不是同种类型,一律返回false
 *      2.使用关键字"instanceof"来做排它性校验
 *          语法:
 *          引用 instanceof 类名/接口名
 *          该结构用于判断引用所指向的对象是否是后面类型的对象,或者子类对象(后面的类名写的是普通类)
 *              如果后面写的是抽象类的类名或者接口名,那么就是判断引用所指向的对象是否是后面类名的子类对象
 *          用instanceof做排它性校验时
 *          条件更为宽松
 *          允许子类对象传入方法,并不会返回false
 *
 * 两种排它性校验,根据情况来选择
 * 当然,一般来说,方式一是更常见的
 *
 * @since 14:23
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo2 {
    public static void main(String[] args) {
        Teacher t1 = new Teacher(10000, 18, 1);
        Teacher t2 = new Teacher(10000, 18, 1);
        System.out.println(t1.equals(t2));
        TeacherSon ts = new TeacherSon(10000, 18, 1);
        System.out.println(t1.equals(ts));
    }
}

class Teacher {
    double salary;
    int age;
    int staffId;

    public Teacher(double salary, int age, int staffId) {
        this.salary = salary;
        this.age = age;
        this.staffId = staffId;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        // 不允许传入子类对象,只允许传入相同类型对象
        if (o == null || getClass() != o.getClass()) return false;

        Teacher teacher = (Teacher) o;

        if (Double.compare(teacher.salary, salary) != 0) return false;
        if (age != teacher.age) return false;
        return staffId == teacher.staffId;
    }

    /* @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        // 允许接收子类对象的传入
        if (!(o instanceof Teacher)) return false;

        Teacher teacher = (Teacher) o;

        if (Double.compare(teacher.salary, salary) != 0) return false;
        if (age != teacher.age) return false;
        return staffId == teacher.staffId;
    }*/

    @Override
    public int hashCode() {
        int result;
        long temp;
        temp = Double.doubleToLongBits(salary);
        result = (int) (temp ^ (temp >>> 32));
        result = 31 * result + age;
        result = 31 * result + staffId;
        return result;
    }

/*@Override
    public boolean equals(Object obj) {
        // 自反性
        if (this == obj) {
            return true;
        }
        // 排它性用getClass实现
        if (obj == null || getClass() != obj.getClass()){
            return false;
        }
        // 排它性用instanceof实现
       *//* if (!(obj instanceof Teacher)) {
            // 表示obj指向的对象既不是Teacher对象,也不是Teacher的子类对象
            // 而且null instanceof 类名 一定返回false,所以这里也不需要判断null了
            return false;
        }*//*

        // 对称性 传递性 一致性只需要按照对象的属性取值来判断对象相等就自动满足了
        Teacher t = (Teacher) obj;
        if (salary != t.salary) {
            return false;
        }
        if (age != t.age) {
            return false;
        }
        return staffId == t.staffId;
    }*/
}

class TeacherSon extends Teacher {
    public TeacherSon(double salary, int age, int staffId) {
        super(salary, age, staffId);
    }
}